function Vector(a, b) {
  this.x = a
  this.y = b
}
Vector.prototype = {
  rotate: function (b) {
    var a = this.x
    var c = this.y
    this.x = Math.cos(b) * a - Math.sin(b) * c
    this.y = Math.sin(b) * a + Math.cos(b) * c
    return this
  },
  mult: function (a) {
    this.x *= a
    this.y *= a
    return this
  },
  clone: function () {
    return new Vector(this.x, this.y)
  },
  length: function () {
    return Math.sqrt(this.x * this.x + this.y * this.y)
  },
  subtract: function (a) {
    this.x -= a.x
    this.y -= a.y
    return this
  },
  set: function (a, b) {
    this.x = a
    this.y = b
    return this
  },
}
function Petal(a, f, b, e, c, d) {
  this.stretchA = a
  this.stretchB = f
  this.startAngle = b
  this.angle = e
  this.bloom = d
  this.growFactor = c
  this.r = 1
  this.isfinished = false
}
Petal.prototype = {
  draw: function () {
    var a = this.bloom.garden.ctx
    var e, d, c, b
    e = new Vector(0, this.r).rotate(Garden.degrad(this.startAngle))
    d = e.clone().rotate(Garden.degrad(this.angle))
    c = e.clone().mult(this.stretchA)
    b = d.clone().mult(this.stretchB)
    a.strokeStyle = this.bloom.c
    a.beginPath()
    a.moveTo(e.x, e.y)
    a.bezierCurveTo(c.x, c.y, b.x, b.y, d.x, d.y)
    a.stroke()
  },
  render: function () {
    if (this.r <= this.bloom.r) {
      this.r += this.growFactor
      this.draw()
    } else {
      this.isfinished = true
    }
  },
}
function Bloom(e, d, f, a, b) {
  this.p = e
  this.r = d
  this.c = f
  this.pc = a
  this.petals = []
  this.garden = b
  this.init()
  this.garden.addBloom(this)
}
Bloom.prototype = {
  draw: function () {
    var c,
      b = true
    this.garden.ctx.save()
    this.garden.ctx.translate(this.p.x, this.p.y)
    for (var a = 0; a < this.petals.length; a++) {
      c = this.petals[a]
      c.render()
      b *= c.isfinished
    }
    this.garden.ctx.restore()
    if (b == true) {
      this.garden.removeBloom(this)
    }
  },
  init: function () {
    var c = 360 / this.pc
    var b = Garden.randomInt(0, 90)
    for (var a = 0; a < this.pc; a++) {
      this.petals.push(
        new Petal(
          Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max),
          Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max),
          b + a * c,
          c,
          Garden.random(Garden.options.growFactor.min, Garden.options.growFactor.max),
          this
        )
      )
    }
  },
}
function Garden(a, b) {
  this.blooms = []
  this.element = b
  this.ctx = a
}
Garden.prototype = {
  render: function () {
    for (var a = 0; a < this.blooms.length; a++) {
      this.blooms[a].draw()
    }
  },
  addBloom: function (a) {
    this.blooms.push(a)
  },
  removeBloom: function (a) {
    var d
    for (var c = 0; c < this.blooms.length; c++) {
      d = this.blooms[c]
      if (d === a) {
        this.blooms.splice(c, 1)
        return this
      }
    }
  },
  createRandomBloom: function (a, b) {
    this.createBloom(
      a,
      b,
      Garden.randomInt(Garden.options.bloomRadius.min, Garden.options.bloomRadius.max),
      Garden.randomrgba(
        Garden.options.color.rmin,
        Garden.options.color.rmax,
        Garden.options.color.gmin,
        Garden.options.color.gmax,
        Garden.options.color.bmin,
        Garden.options.color.bmax,
        Garden.options.color.opacity
      ),
      Garden.randomInt(Garden.options.petalCount.min, Garden.options.petalCount.max)
    )
  },
  createBloom: function (a, f, d, e, b) {
    new Bloom(new Vector(a, f), d, e, b, this)
  },
  clear: function () {
    this.blooms = []
    this.ctx.clearRect(0, 0, this.element.width, this.element.height)
  },
}
Garden.options = {
  petalCount: { min: 8, max: 15 },
  petalStretch: { min: 0.1, max: 3 },
  growFactor: { min: 0.1, max: 1 },
  bloomRadius: { min: 8, max: 10 },
  density: 10,
  growSpeed: 1000 / 60,
  color: { rmin: 128, rmax: 255, gmin: 0, gmax: 128, bmin: 0, bmax: 128, opacity: 0.1 },
  tanAngle: 60,
}
Garden.random = function (b, a) {
  return Math.random() * (a - b) + b
}
Garden.randomInt = function (b, a) {
  return Math.floor(Math.random() * (a - b + 1)) + b
}
Garden.circle = 2 * Math.PI
Garden.degrad = function (a) {
  return (Garden.circle / 360) * a
}
Garden.raddeg = function (a) {
  return (a / Garden.circle) * 360
}
Garden.rgba = function (f, e, c, d) {
  return 'rgba(' + f + ',' + e + ',' + c + ',' + d + ')'
}
Garden.randomrgba = function (i, n, h, m, l, d, k) {
  var c = Math.round(Garden.random(i, n))
  var f = Math.round(Garden.random(h, m))
  var j = Math.round(Garden.random(l, d))
  var e = 5
  if (Math.abs(c - f) <= e && Math.abs(f - j) <= e && Math.abs(j - c) <= e) {
    return Garden.rgba(i, n, h, m, l, d, k)
  } else {
    return Garden.rgba(c, f, j, k)
  }
}
